package com.sys.plat.util;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AbstractRefreshableWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SpringUtil {
	private static Log log = LogFactory.getLog(SpringUtil.class);
	private static  PathMatcher pathMatcher = new AntPathMatcher();

	@SuppressWarnings("unchecked")
	protected static void doRetrieveMatchingFiles(String fullPattern, File dir,
			Set result) throws IOException {
		File[] dirContents = dir.listFiles();
		if (dirContents == null) {
			throw new IOException("Could not retrieve contents of directory ["
					+ dir.getAbsolutePath() + "]");
		}
		boolean dirDepthNotFixed = (fullPattern.indexOf("**") != -1);
		for (int i = 0; i < dirContents.length; i++) {
			String currPath = StringUtils.replace(dirContents[i]
					.getAbsolutePath(), File.separator, "/");
			if (dirContents[i].isDirectory()
					&& (dirDepthNotFixed || StringUtils.countOccurrencesOf(
							currPath, "/") < StringUtils.countOccurrencesOf(
							fullPattern, "/"))) {
				doRetrieveMatchingFiles(fullPattern, dirContents[i], result);
			}
			fullPattern = StringUtils.replace(fullPattern, File.separator, "/");
			if (pathMatcher.match(fullPattern, currPath)) {
				result.add(dirContents[i]);
			}
		}
	}

	@SuppressWarnings("unchecked")
	public static void reLoadSpringConfig(ServletContext context) throws IOException {
		Long currentTimeStamp = (Long) context
				.getAttribute("SPRINGCONFIGFILE_LASTMODIFY");
		String realPath = context.getRealPath("/");
		String configString = context.getInitParameter("contextConfigLocation");
		String[] configStrs = configString.split(",");
		Long configTimestamp = 0L;
		Set result = new HashSet();
		for (String str : configStrs) {
			str = StringUtils.replace(str,"classpath*:", "");
			String dir = realPath + StringUtils.replace("WEB-INF/classes/", "/", File.separator);
			doRetrieveMatchingFiles(dir + str, new File(dir), result);
		}
		
		configTimestamp += getStrutsConfigTimestamp(result);
		if (currentTimeStamp != null
				&& !currentTimeStamp.equals(configTimestamp)) {
			//  relaod
			log.info("Spring context reload");
			WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
			((AbstractRefreshableWebApplicationContext)ctx).refresh();
		}
		context.setAttribute("SPRINGCONFIGFILE_LASTMODIFY", configTimestamp);
	}

	@SuppressWarnings("unchecked")
	public static Long getStrutsConfigTimestamp(Set result) {
		Long strutsConfigTimestamp = 0L;
		Iterator it = result.iterator();
		while (it.hasNext()) {
			File file = (File) it.next();
			strutsConfigTimestamp += file.lastModified();
		}
		return strutsConfigTimestamp;
	}
}
